package fragments;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.matchcalendar.R;

import dataFormat.CalendarTextData;
import dataFormat.TimeDayPair;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.SparseArray;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;

public class ScheduleControlFragment extends Fragment {
	private LinearLayout linearLayoutSchedule;
	private ScrollView scrollViewSchedule;
	private Map<ImageView, TimeDayPair> imgTimeDayPairMap = new HashMap<ImageView, TimeDayPair>();
	private ImageView clickedView;
	private int nowHeight = 50;
	private double unitHeight = nowHeight / 60.;
	private View rootView;
	private boolean isAddScheduleEnabled;
	private SparseArray<CalendarTextData> idCalTextDataMap = new SparseArray<CalendarTextData>();
	private Map<CalendarTextData, TextView> calDataTextViewMap = new HashMap<CalendarTextData, TextView>();
	private Calendar weekCal;
	private int nowId = 0;
	
	public ScheduleControlFragment(boolean isAddScheduleEnabled, Calendar weekCal) {
		this.isAddScheduleEnabled = isAddScheduleEnabled;
		this.weekCal = weekCal;
	}
	
	protected Map<ImageView, TimeDayPair> getImgTimeDayPairMap() {
		return imgTimeDayPairMap;
	}
	
	public Set<CalendarTextData> getCalendarTextDataSet() {
		return calDataTextViewMap.keySet();
	}
	
	public ImageView getClickedView() {
		return clickedView;
	}
	
	protected void setNowHeight(int nowHeight) {
		this.nowHeight = nowHeight;
	}
	
	protected void setUnitHeight(double unitHeight) {
		this.unitHeight = unitHeight;
	}
	
	protected int getNowHeight() {
		return nowHeight;
	}
	
	protected double getUnitHeight() {
		return unitHeight;
	}
	
	public Calendar getWeekCal() {
		return weekCal;
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		rootView = inflater.inflate(R.layout.custom_add_schedule_view, container, false);
        findView();
		setListenerOrAdapter();
		initView();
        return rootView;
    }

	private void findView() {
		linearLayoutSchedule = (LinearLayout) rootView.findViewById(R.id.linearLayoutSchedule);
		scrollViewSchedule = (ScrollView) rootView.findViewById(R.id.scrollViewSchedule);
	}
	
	private void setListenerOrAdapter() {
		scrollViewSchedule.setOnTouchListener(new ScrollViewScheduleTouch());
	}
	
	private class ScrollViewScheduleTouch implements ScrollView.OnTouchListener {
		private double oldDistance = -1;

		@Override
		public boolean onTouch(View view, MotionEvent event) {
			switch (event.getAction()) {
				case MotionEvent.ACTION_MOVE:
					if (event.getPointerCount() == 2) {
						double newDistance = Math.sqrt(Math.pow(
								event.getX(0) - event.getX(1), 2)  + Math.pow(event.getY(0) - event.getY(1), 2));
						
						if (oldDistance != -1) {
							int diff = (int) ((newDistance - oldDistance) * 0.5);
							int calResult = nowHeight + diff;
							
							if (calResult < 50)
								nowHeight = 50;
							else if (calResult > 260)
								nowHeight = 260;
							else
								nowHeight = nowHeight + diff;
							unitHeight = nowHeight / 60.;
							for (int i=0; i<=23; i++) {
								LinearLayout.LayoutParams timeTextParams =
										(LinearLayout.LayoutParams) rootView.findViewById((i + 1) * 10).getLayoutParams();
								
								timeTextParams.height = nowHeight;
								rootView.findViewById((i + 1) * 10).setLayoutParams(timeTextParams);
								for (int j=0; j<=6; j++) {
									RelativeLayout.LayoutParams params =
											(RelativeLayout.LayoutParams) rootView.findViewById((i + 1) * 10 + j + 1).getLayoutParams();
									
									params.height = nowHeight;
									rootView.findViewById((i + 1) * 10 + j + 1).setLayoutParams(params);
								}
							}
							for (CalendarTextData data: calDataTextViewMap.keySet()) {
								RelativeLayout.LayoutParams params =
										(RelativeLayout.LayoutParams) calDataTextViewMap.get(data).getLayoutParams();
								
								params.setMargins(1, (int)(data.getStartMinute() * unitHeight), 1,
										(data.getOverMinute() == 0)? nowHeight:(int)((60 - data.getOverMinute()) * unitHeight));
								calDataTextViewMap.get(data).setLayoutParams(params);
							}
						}
						oldDistance = newDistance;
					}
					break;
				case MotionEvent.ACTION_UP:
					oldDistance = -1;
					onHeightChange();
			}
			return false;
		}
	}
	
	protected void onHeightChange() {
	}
	
	private void initView() {
		if (weekCal != null) {
			Calendar displayCal = Calendar.getInstance();
			
			displayCal.set(weekCal.get(Calendar.YEAR), weekCal.get(Calendar.MONTH), weekCal.get(Calendar.DATE));
			for (int i=0; i<=6; i++) {
				TextView textViewDay = null;
				
				switch (i) {
					case 0:
						textViewDay = ((TextView)rootView.findViewById(R.id.textViewSunday));
						break;
					case 1:
						textViewDay = ((TextView)rootView.findViewById(R.id.textViewMonday));
						break;
					case 2:
						textViewDay = ((TextView)rootView.findViewById(R.id.textViewTuesday));
						break;
					case 3:
						textViewDay = ((TextView)rootView.findViewById(R.id.textViewWednesday));
						break;
					case 4:
						textViewDay = ((TextView)rootView.findViewById(R.id.textViewThursday));
						break;
					case 5:
						textViewDay = ((TextView)rootView.findViewById(R.id.textViewFriday));
						break;
					case 6:
						textViewDay = ((TextView)rootView.findViewById(R.id.textViewSaturday));
				}
				textViewDay.setText(textViewDay.getText() + "\n" + displayCal.get(Calendar.DATE));
				displayCal.add(Calendar.DATE, 1);
			}
		}
		for (int i=0; i<=23; i++) {
			TextView timeText = new TextView(getActivity());
			LinearLayout.LayoutParams timeTextParams = new LinearLayout.LayoutParams(
					LinearLayout.LayoutParams.MATCH_PARENT, nowHeight);
			
			timeText.setId((i + 1) * 10);
			timeTextParams.setMargins(0, 1, 0, 0);
			timeText.setLayoutParams(timeTextParams);
			timeText.setBackgroundResource(R.color.gray6);
			timeText.setGravity(Gravity.CENTER_HORIZONTAL);
			timeText.setTextSize(12);
			if (i < 10)
				timeText.setText("0" + i);
			else
				timeText.setText(String.valueOf(i));
			((LinearLayout)linearLayoutSchedule.getChildAt(0)).addView(timeText);
			for (int j=0; j<=6; j++) {
				ImageView timeSegment = new ImageView(getActivity());
				RelativeLayout.LayoutParams textParams = new RelativeLayout.LayoutParams(
						RelativeLayout.LayoutParams.MATCH_PARENT, nowHeight);
				
				timeSegment.setId((i + 1) * 10 + j + 1);
				if (i == 0)
					textParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
				else
					textParams.addRule(RelativeLayout.BELOW, i * 10 + j + 1);
				textParams.setMargins(1, 1, 0, 0);
				timeSegment.setLayoutParams(textParams);
				timeSegment.setBackgroundResource(R.color.gray6);
				if (isAddScheduleEnabled)
					timeSegment.setOnClickListener(new TimeSegmentClick());
				imgTimeDayPairMap.put(timeSegment, new TimeDayPair(i, j));
				((RelativeLayout)linearLayoutSchedule.getChildAt(j + 1)).addView(timeSegment);
			}
		}
	}
	
	private class TimeSegmentClick implements ImageView.OnClickListener {

		@Override
		public void onClick(View view) {
			if (clickedView != (ImageView)view) {
				if (clickedView != null) {
					clickedView.setImageDrawable(null);
					clickedView.setBackgroundResource(R.color.gray6);
				}
				clickedView = (ImageView)view;
				clickedView.setImageResource(android.R.drawable.ic_input_add);
				clickedView.setBackgroundResource(R.color.blue4);
			}
			else {
				clickAddSchedule(view);
				clickedView.setImageDrawable(null);
				clickedView.setBackgroundResource(R.color.gray6);
				clickedView = null;
			}
		}
	}
	
	public void addCalendarText(CalendarTextData calTextData, TextView.OnClickListener calTextClick,
			TextView.OnLongClickListener calTextLongClick, int textGravity) {
		TextView calText = new TextView(getActivity());
		RelativeLayout.LayoutParams informTextParams = new RelativeLayout.LayoutParams(
				RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
		int originalColor = 0;
		
		calTextData.setId(nowId);
		idCalTextDataMap.put(nowId, calTextData);
		nowId++;
		calDataTextViewMap.put(calTextData, calText);
		calTextHeightFormula(calTextData, informTextParams);
		calText.setLayoutParams(informTextParams);
		calText.setGravity(textGravity);
		calText.setText(calTextData.getTitle());
		switch (calTextData.getPriority()) {
			case -1:
				calText.setBackgroundResource(R.color.transparentGreen1);
				originalColor = R.color.transparentGreen1;
				break;
			case 0:
				calText.setBackgroundResource(R.color.transparentGray1);
				originalColor = R.color.transparentGray1;
				break;
			case 1:
				calText.setBackgroundResource(R.color.transparentYellow1);
				originalColor = R.color.transparentYellow1;
				break;
			case 2:
				calText.setBackgroundResource(R.color.transparentRed1);
				originalColor = R.color.transparentRed1;
		}
		calText.setOnTouchListener(new CalendarTextTouch(originalColor));
		calText.setOnClickListener(calTextClick);
		calText.setOnLongClickListener(calTextLongClick);
		((RelativeLayout)linearLayoutSchedule.getChildAt(calTextData.getDay() + 1)).addView(calText);
	}
	
	public void removeCalendarText(int removeId) {
		CalendarTextData calData = idCalTextDataMap.get(removeId);
		
		((RelativeLayout)linearLayoutSchedule.getChildAt(calData.getDay() + 1)).
		removeView(calDataTextViewMap.get(calData));
		calDataTextViewMap.remove(calData);
		idCalTextDataMap.remove(removeId);
	}
	
	private class CalendarTextTouch implements TextView.OnTouchListener {
		private int originalColor;
		
		public CalendarTextTouch(int originalColor) {
			this.originalColor = originalColor;
		}

		@Override
		public boolean onTouch(View view, MotionEvent event) {
			if (event.getAction() == MotionEvent.ACTION_DOWN)
				view.setBackgroundResource(R.color.blue4);
			else if (event.getAction() == MotionEvent.ACTION_UP ||
					event.getAction() == MotionEvent.ACTION_CANCEL)
				view.setBackgroundResource(originalColor);
			return false;
		}
	}

	protected void clickAddSchedule(View view) {
	}
	
	protected void resetHeight() {
		for (int i=0; i<=23; i++) {
			TextView timeText = (TextView) linearLayoutSchedule.findViewById((i + 1) * 10);
			LinearLayout.LayoutParams timeTextParams = (LinearLayout.LayoutParams) timeText.getLayoutParams();
			
			timeTextParams.height = nowHeight;
			timeText.setLayoutParams(timeTextParams);
			for (int j=0; j<=6; j++) {
				ImageView timeSegment = (ImageView) linearLayoutSchedule.findViewById((i + 1) * 10 + j + 1);
				RelativeLayout.LayoutParams textParams = (RelativeLayout.LayoutParams) timeSegment.getLayoutParams();
				
				textParams.height = nowHeight;
				timeSegment.setLayoutParams(textParams);
			}
		}
		for (CalendarTextData calTextData: calDataTextViewMap.keySet()) {
			TextView calText = calDataTextViewMap.get(calTextData);
			RelativeLayout.LayoutParams calTextParams = (RelativeLayout.LayoutParams) calText.getLayoutParams();
			
			calTextHeightFormula(calTextData, calTextParams);
			calText.setLayoutParams(calTextParams);
		}
	}
	
	private void calTextHeightFormula(CalendarTextData calTextData,
			RelativeLayout.LayoutParams informTextParams) {
		informTextParams.addRule(RelativeLayout.ALIGN_TOP,
				(calTextData.getStartHour() + 1) * 10 + calTextData.getDay() + 1);
		informTextParams.addRule(RelativeLayout.ALIGN_BOTTOM,
				(calTextData.getOverHour() + 1) * 10 + calTextData.getDay() + 1);
		informTextParams.setMargins(1, (int)(calTextData.getStartMinute() * unitHeight), 1,
				(calTextData.getOverMinute() == 0)? nowHeight:(int)((60 - calTextData.getOverMinute()) * unitHeight));
	}
}
